Python: Implement message filtering in agent workflow to stop emitting already seen responses#4268
Python: Implement message filtering in agent workflow to stop emitting already seen responses#4268leelakarthik wants to merge 2 commits intomicrosoft:mainfrom
Conversation
…ng messages in response Add a method to filter messages and update message handling. This helps remove the user messages being duplicated/emitted in the response This fixes the microsoft#4261 for both streaming and non streaming functions
97fedac to
85070bc
Compare
…ge] filtering expectations (microsoft#4261) - Update test_workflow_as_agent_yield_output_with_list_of_chat_messages to reflect _filter_messages semantics: only the last meaningful assistant message is surfaced from list[Message] output, preventing user input re-emission and full conversation history replay. - Add TestWorkflowAgentUserInputFilteringRegression with multi-turn compounding regression tests for both streaming and non-streaming paths, reproducing the exact escalating symptom from microsoft#4261. Users who need intermediate agent responses can opt in via intermediate_outputs=True in GroupChatBuilder.
@microsoft-github-policy-service agree |
Updated: Added tests and clarified filtering rationaleWhat this fixesIssue #4261: When a GroupChat orchestrator terminates, it yields Root cause analysisThe termination path in # _check_terminate_and_yield / _check_agent_terminate_and_yield
await ctx.yield_output(self._full_conversation) # list[Message]This hits the Fix:
|
|
@copilot review |
Summary
Fixes #4261
When a GroupChat orchestrator terminates, it yields
self._full_conversation(the entire conversation history) via
ctx.yield_output(). Without filtering,WorkflowAgent converts all messages — including user inputs and earlier assistant
responses — into output, causing them to compound across successive turns.
Root Cause
The termination path in
BaseGroupChatOrchestratorcallsctx.yield_output(self._full_conversation)which is alist[Message]. This hitsthe
list[Message]branch in both_convert_workflow_event_to_agent_response_updates(streaming) and
_convert_workflow_events_to_agent_response(non-streaming), whereall messages were forwarded without filtering.
Fix
Added
_filter_messages()that returns only the last meaningful assistant messagefrom
list[Message]output. This is intentionally aggressive because:including them again causes duplication
GroupChatBuilderdefaults tointermediate_outputs=False. Users who need intermediate responses can opt invia
intermediate_outputs=TrueRelationship to #4275
PR #4275 filters the
AgentResponsebranch. This PR filters thelist[Message]branch — the actual code path hit by GroupChat's termination yield. Both fixes are
complementary.
Tests
test_workflow_as_agent_yield_output_with_list_of_chat_messagestoreflect new filtering semantics
TestWorkflowAgentUserInputFilteringRegressionwith multi-turn compoundingregression tests for streaming and non-streaming paths
Contribution Checklist